<template>
  <div class='assistant-contain' id="assistantContain" v-show="isShowAssistant">
    <div class="header-section">
      <div class="assistant-title">你好，欢迎使用AI助手!</div>
      <div class="close-icon" @click="closeAssistant">x</div>
    </div>
    <div v-for="(item,index) in $assistantAbilities" :key="index">{{item.name}}</div>
    <div class="content">
      <div class="content-detail">
        <div id="chatBox" class="content-chat">
          <template v-for="(item,index) in qaDataArray" :key="index">
            <div v-if="item.type == 'answer'" class="text-left">
              <div class="answer-wraper">
              <div class="answer" v-html="item.value">
              </div>
              <div class="answer-handle">
                <!-- <div v-if="item.user_id == user_id" class="answer-align" @click="fetchDataStream">重新生成</div> -->
                <div @click="copyText(index)" class="answer-copy">复制</div>
                <div class="answer-copy-success" v-show="item?.copySuccess">复制成功</div>
              </div>
              </div>
            </div>
            <div v-if="item.type == 'question'" class="text-right">
              <div class="question">{{ item.value }}</div>
            </div>
          </template>
        </div>
        <!-- 停止作答？   新建对话  历史对话  选中本框中的文本不出现弹窗 隐藏，出现 挂载  图标  历史弹窗选择   绑定事件解除  输入限制-->
        <div class="assistant-footer">
          <div class="article-section" v-if="selectContent">
            <div class="article-lable">是否对选中文本进行操作？</div>
            <div class="article-content">{{ selectContent }}</div>
            <div class="article-handle" @click="articleSelectHandle">提问</div>
          </div>
          <div class="fun-section-list">
            <div class="btn-item" @click="newDialog">
              +新建对话
            </div>
            <div class="btn-item" @click="showHistory">
              #历史对话
            </div>
            <div class="history-list-wraper" v-show="historyList && !selectContent">
              <div>历史对话</div>
              <ul>
                <li>历史对话11 &nbsp;&nbsp;&nbsp;&nbsp;<span>X</span></li>
                <li>历史对话22 &nbsp;&nbsp;&nbsp;&nbsp;<span>X</span></li>
              </ul>
            </div>
          </div>
          <div class="input-wraper">
            <textarea
              :rows="4"
              @keyup.enter="submit('enter')"
              placeholder="请输入你的问题"
              v-model="question">
            </textarea>
            <button class="action-button" type="button" @click="submit">发送</button>
          </div>
        </div>
      </div>
    </div>
  </div>
  <button class="popup-button" id="popupButton">问问AI助手</button>
  <button class="popup-button assistant-icon" v-show="!isShowAssistant" @click="showAssistant" >AI助手</button>
</template>
<script>
import { fetchEventSource } from "@microsoft/fetch-event-source";
export default {
  name: "AssistantMain",
  props:{
    options:[]
  },
  data () {
    return{
      qaDataArray: [
      //   {
      //   type:"question",
      //   value:"大模型，支持"
      // },{
      //   type:"answer",
      //   value:"大模型，支持11",
      //   user_id:1
      // },{
      //   type:"question",
      //   value:"大模型，支持"
      // },{
      //   type:"answer",
      //   value:"大模型，支持4444",
      //   user_id:2
      // }
      ],
      question: "",
      nowQuestionValue: "",
      user_id: 1,
      answerValue: "",
      fetchDataStream: null,
      session_id: new Date().getTime(),
      selectContent:"",
      onSelf:false,
      isShowAssistant:true,
      copySuccess:false,
      historyList:false

    };
  },
  created () {
    this.initData();
    console.log("assistantAbilities",this.$assistantAbilities);
  },
  mounted(){
    this.initHandle();
    this.$isShowAssistant(true);
  },
  methods: {
    closeAssistant(){
      this.isShowAssistant = false;
      this.$isShowAssistant(false);
    },
    showAssistant(){
      this.isShowAssistant = true;
      this.$isShowAssistant(true);
      this.newDialog();
    },
    async copyText(index) {
      try {
        await navigator.clipboard.writeText(this.qaDataArray[index].value);
        this.qaDataArray[index].copySuccess = true;
        setTimeout(()=>{
          this.qaDataArray[index].copySuccess = false;
        },1000);
        // 可以在这里添加用户反馈，比如弹窗提示复制成功
      } catch (err) {
        console.error('复制失败', err);
      }
    },
    initHandle(){
      document.addEventListener('mouseup',  (event) => {
        if(event.target?.id == 'popupButton') return;
        const selection = window.getSelection();
        const button = document.getElementById('popupButton');
        //使用setTimeout 防止选中后第一次click事件还有内容使得节点还在
        setTimeout(()=>{
          if (selection.toString().length > 0 && !this.onSelf) { // 确保有文本被选中
            console.log(1,selection);
            this.selectContent = selection.toString();
            this.historyList = false;
            button.style.display = 'block';
            button.style.left = `${event.clientX+window.scrollX+10}px`;
            button.style.top = `${event.clientY+window.scrollY+10}px`;

            // 添加按钮点击事件处理程序
            button.onclick = () => {
              this.isShowAssistant = true;
              this.qaDataArray = [];
              this.articleSelectHandle();
              // 在这里执行你想要的操作
              button.style.display = 'none'; // 隐藏按钮
          };
        } else {
          button.style.display = 'none'; // 如果没有文本被选中，则隐藏按钮
          this.selectContent = "";
        }
        });
      });

      
      // 获取要监听的元素
      const element = document.getElementById('assistantContain');
      // 鼠标进入元素边界时触发
      element.addEventListener('mouseenter', () => {
        this.onSelf = true;
        console.log('鼠标现在在元素上方');
      });
      
      // 鼠标离开元素边界时触发
      element.addEventListener('mouseleave', () => {
        this.onSelf = false;
        console.log('鼠标已离开元素');
      });
    },
    //提问
    articleSelectHandle(){
      this.question = this.selectContent;
      this.submit();
    },
    initData () {
      this.fetchDataStream = () => {
        let that = this;
        const ctrl = new AbortController();
        fetchEventSource("http://192.168.32.102:8100/generate_stream", {
          method: "POST",
          headers: {
            "Content-Type": "application/json"
          },
          body: JSON.stringify({
            "session_id": that.session_id,
            "inputs": that.nowQuestionValue,
            "user_id": that.user_id,
            "model": "jiutian-med-14b-v0"
          }),
          signal: ctrl.signal,
          onclose () {
          // 正常结束的回调
          ctrl?.abort();
          // throw new RetriableError();
          },
          onmessage (event) {
            if (event.data === "[DONE]") {
              console.log("Stream ended");
              return;
            }
            let data = JSON.parse(JSON.parse(event.data));

            if(that.currentId == that.user_id
          && that.qaDataArray[that.qaDataArray.length - 1].user_id == that.user_id
          && that.qaDataArray[that.qaDataArray.length - 1].type == "answer") {
              that.qaDataArray[that.qaDataArray.length - 1].value = data.generated_text;
            }
            else if(that.currentId != that.user_id ) {
              let answerItem = {
                type: "answer",
                value: data.generated_text,
                user_id: that.user_id
              };
              that.qaDataArray.push(answerItem);
            }
            that.currentId = that.user_id;
            that.$nextTick(()=>{
              var message = document.getElementById("chatBox");
              message.scrollTop = message.scrollHeight;
            });
          },
          onerror (error) {
            console.error("Stream encountered error:", error);
          }
        });
      };
    },
    submit (type) {
      //去掉回车的换行符
      if(type == "enter") {
        this.question = this.question.substring(0,this.question.length - 1);
      }
      if(!this.question) {
        return ;
      }
      this.selectContent = "";
      ++this.user_id;
      this.qaDataArray.push({
        type: "question",
        value: this.question,
        user_id: this.user_id
      });
      this.nowQuestionValue = this.question;
      this.question = "";

      this.fetchDataStream();
      this.$nextTick(()=>{
        var message = document.getElementById("chatBox");
        message.scrollTop = message.scrollHeight;
      });
    },
    newDialog(){
      this.qaDataArray = [];
      this.selectContent = "";
      // this.user_id = 1;
    },
    showHistory(){
      this.historyList = !this.historyList;
      //获取接口
    }
  }

};
</script>
<style>
.assistant-contain {
  position:absolute;
  top:0px;
  right:-400px;
  width: 400px;
  height:100%;
  /* padding: 20px 0; */
  /* margin:0; */
  box-sizing:border-box;
  background: linear-gradient(180deg, #d7ebf9, #fff 60%, #fff 80%);
  box-shadow: -4px 0 16px 0 rgb(0 0 0 / 12%);
  border-radius: 5px;
}

.assistant-contain .header-section{
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 12px;
}

.assistant-contain .assistant-title{
  font-size: 18px;
  font-weight: 600;
  height: 40px;
  line-height: 40px;
}

.close-icon{
  font-size: 16px;
  cursor: pointer;
}

.assistant-contain .content {
  height: calc(100% - 40px);
  font-size: 16px;
  font-weight: 500;
  border-radius: 18px;
  box-sizing: border-box;
}

.content-top {
  display: flex;
  justify-content: space-between;
  padding: 16px;
  background: #f1f5ff;
  border-radius: 18px 18px 0 0;

  /* flex-direction: */
}

.content-chat {
  height: calc(100% - 200px);
  padding-bottom: 20px;
  overflow-y: auto;
  box-sizing: border-box;
}

/* 整个滚动条 */
::-webkit-scrollbar {
  width: 6px; /* 设置滚动条的宽度 */
}

/* 滚动条轨道 */
::-webkit-scrollbar-track {
  background: #f1f1f1; /* 设置轨道的背景颜色 */
}

/* 滚动条的滑块 */
::-webkit-scrollbar-thumb {
  background: #aaa; /* 设置滑块的背景颜色 */
}

/* 当鼠标悬停在滑块上 */
::-webkit-scrollbar-thumb:hover {
  background: #555; /* 设置滑块在悬停状态下的背景颜色 */
}

.input-wraper {
  position: relative;
  border: 2px solid #999;
  border-radius: 12px;
}
.input-wraper  textarea {
    width:100%;
    padding: 12px 12px 60px;
    font-size: 15px;
    box-sizing: border-box;
    border: none;
    border-radius: 12px;
  }
  .input-wraper textarea:focus{
  outline:none
  }


.action-button {
  position: absolute;
  right: 16px;
  bottom: 16px;
  width: 80px;
  height: 40px;
  color: white;
  cursor: pointer;
  background: linear-gradient(90deg, #43b0fe 0%, #1065fc 100%);
  border: 0;
  border-radius: 8px;
}

.content-detail {
  height: 100%;
  padding: 16px;
  box-sizing: border-box;
}

.content-label {
  font-size: 18px;
  font-weight: 600;
}

.el-select .el-input__inner {
  font-size: 16px;
}

.text-left {
  display: flex;
  align-items: flex-start;
  margin-bottom: 20px;
}

.text-right {
  display: flex;
  justify-content: flex-end;
  align-items: flex-start;
  margin-bottom: 20px;
}

.answer-wraper {
  width: 100%;
  background: #f6fafd;
  padding-bottom: 30px;
  border-radius: 6px;
  padding: 12px;
  box-sizing: border-box;
  text-align: left;
}
.answer-handle{
  display: flex;
  justify-content: flex-end;
  color: #43b0fe;
  position: relative;
  margin-top: 12px;

}

.answer-align,
.answer-copy{
  margin-right: 12px;
  cursor: pointer;
}
.answer-copy-success{
  position: absolute;
  display: inline-block;
  padding: 12px;
  background: #333;
  border-radius: 12px;
  color: white;
  top: -50px;
  font-size: 12px;
}

.tips {
  padding: 100px 0;
  font-size: 14px;
  color: #a3a3a3;
  text-align: center;
}

.align {
  margin-top: 1px;
  cursor: pointer;
}

.align img {
  width: 89px;
  height: 27px;
}

.question {
  max-width: 100%;
  padding: 10px;
  box-sizing: border-box;
  color: white;
  background: linear-gradient(90deg, #1065fc 0%, #4374fe 100%);
  border-radius: 6px;
  text-align: left;
}
.assistant-footer{
  position: relative;
}
.assistant-footer .fun-section-list{
  display: flex;
  align-items: center;
  justify-content: flex-start;
  margin-bottom: 12px;
  position: relative;
}
.assistant-footer .fun-section-list .btn-item{
  width: 100px;
  height: 40px;
  line-height: 40px;
  border-radius: 6px;
  margin-right: 10px;
  cursor: pointer;
  background: #f3f3f3;
  text-align: center;
}

.assistant-footer .fun-section-list .btn-item:hover{
  background:rgba(31,98,238,.1)
}

.history-list-wraper{
  position: absolute;
  /* background: #f9f9f9; */
  padding: 12px;
  border-radius: 12px;
  text-align: left;
  margin-bottom: 8px;
  bottom: 48px;
  width: calc(100% - 112px);
  left:112px;
  box-sizing: border-box;
  border: 1px solid #ebe9e9;
  box-shadow: 0 4px 8px rgb(0 0 0 / 30%);
}

.popup-button {
  position: absolute;
  display: none;
  border: 1px solid #007bff;
  background: white;
  color: #007bff;
  padding: 8px;
  cursor: pointer;
  z-index: 1000;
  border-radius: 10px;
}
.assistant-icon{
  position: fixed;
  display: block;
  bottom: 12px;
  right: 12px;
}

.article-section{
  position: absolute;
  background: white;
  padding: 12px;
  border-radius: 12px;
  text-align: left;
  margin-bottom: 8px;
  bottom: 148px;
  width: 100%;
  box-sizing: border-box;
  border: 1px solid #ebe9e9;
  box-shadow: 0 4px 8px rgb(0 0 0 / 30%);
  z-index: 99;
}

.article-section .article-lable{
 margin-bottom: 20px;
 font-size: 18px;
}
.article-section .article-content{
  width: 100%;
  word-break: break-all;
  text-overflow: ellipsis;
  overflow: hidden;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3; /* 这里是超出几行省略 */
  margin-bottom: 20px;
}
.article-handle{
  text-align: center;
  color: #43b0fe;
  cursor: pointer;
}
</style>